import { AttrType } from "./attr/AttrType";
import { IActionData } from "./common/BattleConst";
import { BattleState } from "./common/BattleState";
import { EnemyMgr } from "./enemy/EnemyMgr";
import { EventId } from "./event/EventId";
import EventMgr from "./event/EventMgr";
import { BattleRole } from "./role/BattleRole";
import { TeamData } from "./role/TeamData";
import { SkillData } from "./skill/const/SkillData";
import { TargetType } from "./skill/const/TargetType";
import { SkillBase } from "./skill/SkillBase";
import { ITriggerResult } from "./trigger/const/ITriggerResult";
import { TriggerType } from "./trigger/const/TriggerType";
import { TriggerMgr } from "./trigger/TriggerMgr";

/**
 * 战斗逻辑管理器
 */
export class BattleManager {

    private static _ins: BattleManager;

    public static get ins(): BattleManager {
        if (!this._ins) {
            this._ins = new BattleManager()
        }
        return this._ins;
    }

    /**战斗内全局触发管理器，一些全局效果在这里注册(可以在技能效果里使用注册全局触发器效果，就不需要写特殊逻辑) */
    private _triggerMgr: TriggerMgr;

    /**所有战斗单位 */
    private roles: BattleRole[]

    /**战斗单位行动队列 */
    private actionQueue: BattleRole[];

    /**当前行动的单位 */
    private _curRole: BattleRole;
    /**行动数据 */
    private _actionData: IActionData;

    /**当前回合 */
    private round: number = 0;

    /**当前战斗帧 */
    private battleFrame: number = 0;

    /**当前战斗状态 */
    private state: BattleState
    init() {

        //监听事件
        EventMgr.ins.on(EventId.BATTLE_STATE, this.battleState, this);
        EventMgr.ins.on(EventId.SELECT_SKILL, this.onSelectSkill, this);
        EventMgr.ins.on(EventId.SELECT_TARGET, this.onSelectTarget, this);
        EventMgr.ins.on(EventId.APPLY_BUFF_EFFECT, this.onApplyBuff, this);
        EventMgr.ins.on(EventId.ROLE_DEAD, this.onRoleDead, this);

        // EventMgr.ins.on(EventId.REMOVE_BUFF, this.onRemoveBuff, this);


        this.roles = [];

        this._triggerMgr = new TriggerMgr()

        //创建我方战斗单位
        let myTeam = TeamData.myTeam();
        for (let i = 0; i < myTeam.length; i++) {
            let role = new BattleRole();
            role.init(myTeam[i]);
            this.roles.push(role);
        }
        //创建敌人单位
        let enemy = EnemyMgr.enemy();
        for (let i = 0; i < enemy.length; i++) {
            let role = new BattleRole();
            role.init(enemy[i]);
            this.roles.push(role);
        }
        //发消息给表现层加入模型
        EventMgr.ins.event(EventId.ADD_ROLES, this.roles);
        setTimeout(() => {
            this.battleState(BattleState.BATTLE_SATRT);
        }, 2000)
    }

    battleState(state: BattleState): void {
        if (this.state == state) return;
        this.state = state;
        switch (state) {
            case BattleState.BATTLE_SATRT:
                this.battleStart();
                break;
            case BattleState.BATTLE_END:
                this.battleEnd();
                break;
            case BattleState.BEFORE_ROUND:
                this.beforeRoundStart();
                break;
            case BattleState.ROUND_START:
                this.roundStart();
                break;
            case BattleState.ROUND_END:
                this.roundEnd();
                break;
            case BattleState.ROLE_ACTION:
                this.roleAction();
                break;
            case BattleState.ROLE_ACTION_END:
                this.roleActionEnd();
                break;
            case BattleState.SELECT_SKILL:
                break;
            case BattleState.SELECT_TARGET:
                break;
            case BattleState.USE_SKILL:
                this.useSkill()
                break;
        }
        //同步状态给ui界面
        EventMgr.ins.event(EventId.BATTLE_STATE_UI, this.state);
    }

    /**战斗开始 */
    battleStart(): void {
        this.round = 0;
        this.actionQueue = []
        //可能有进场技能，加buff之类的
        this.roles.forEach(role => {
            if (role.isAlive()) {
                this.actionQueue.push(role)
            }
        })
        this.battleState(BattleState.BEFORE_ROUND)
    }

    /**战斗结束 */
    battleEnd(): void {

    }

    /**回合开始前(根据移速排序) */
    beforeRoundStart(): void {
        this.actionQueue = [];
        this.roles.forEach(role => {
            if (role.isAlive()) {
                this.actionQueue.push(role)
            }
        })
        this.actionQueue.sort((a: BattleRole, b: BattleRole) => { return a.attrMgr.getAttr(AttrType.speed) - b.attrMgr.getAttr(AttrType.speed) });
        //回合开始前技能
        this.battleState(BattleState.ROUND_START);
    }

    /**回合开始 */
    roundStart(): void {
        this._curRole = this.actionQueue[0];
        if (this._curRole) {//单位行动开始
            this.battleState(BattleState.ROLE_ACTION)
        } else {//角色行动完了，进入回合结束
            this.battleState(BattleState.ROUND_END)
        }
    }

    /**回合结束 */
    roundEnd(): void {
        this.battleState(BattleState.BEFORE_ROUND)
    }

    /**单位行动开始 */
    roleAction(): void {
        if (!this._curRole) return;
        this._actionData = {
            caster: this._curRole,
            skill: null,
            actionType: null,
            targets: [],
        }
        this._curRole.buffMgr.apply(TriggerType.actionStart, this._curRole)
    }

    /**单位行动结束 */
    roleActionEnd(): void {
        this._curRole.buffMgr.checkRemoveBuff();
        this.actionQueue.shift();
        this._curRole.buffMgr.apply(TriggerType.actionStart, this._curRole)
        this.battleState(BattleState.ROUND_START)
    }

    /**选择技能-正常流程，选择技能后根据技能目标数选择目标-全体技能不需要选择目标-直接释放 */
    onSelectSkill(skill: SkillData): void {
        if (this.state != BattleState.SELECT_SKILL) return;
        this._actionData.skill = skill;
        console.log("选择技能", skill.skillName);
        //如果技能是作用于自己或己方全体或对方全体，直接释放
        if (skill.targetType == TargetType.self) {
            this._actionData.targets = [this.curRole]
            this.battleState(BattleState.USE_SKILL)
        } else if (skill.targetType == TargetType.team && skill.targetCount == -1) {
            this._actionData.targets = [];
            for (let i = 0; i < this.roles.length; i++) {
                if (this.roles[i].isAlive() && this.roles[i].roleData.group == this.curRole.roleData.group) {
                    this._actionData.targets.push(this.roles[i])
                }
            }
            this.battleState(BattleState.USE_SKILL)
        } else if (skill.targetType == TargetType.enemy && skill.targetCount == -1) {
            this._actionData.targets = [];
            for (let i = 0; i < this.roles.length; i++) {
                if (this.roles[i].isAlive() && this.roles[i].roleData.group != this.curRole.roleData.group) {
                    this._actionData.targets.push(this.roles[i])
                }
            }
            this.battleState(BattleState.USE_SKILL)
        } else {
            this.battleState(BattleState.SELECT_TARGET);
        }
    }

    /**选择目标-数量满足后释放技能 (如果已存在-取消选择)*/
    onSelectTarget(target: BattleRole): void {
        //还没选技能
        if (this.state != BattleState.SELECT_TARGET) return;
        //判断是否满足技能需要的目标
        let targetType = this._actionData.skill.targetType;
        let isMe = target.uid == this.curRole.uid;
        let isTeam = target.roleData.group == this.curRole.roleData.group;
        if (targetType == TargetType.self && !isMe) return;
        if (targetType == TargetType.teammate && !isTeam || isMe) return;
        if (targetType == TargetType.team && !isTeam) return;
        if (targetType == TargetType.enemy && isTeam) return;
        console.log("选择目标")
        let targets = this._actionData.targets;
        let idx = targets.indexOf(target)
        if (idx == -1) {
            targets.push(target);
            if (targets.length >= this._actionData.skill.targetCount) {
                //目标足够，释放技能
                console.log("释放技能")
                this.useSkill()
            }
        } else {
            targets.splice(idx, 1);
        }
    }

    /**技能伤害计算 */
    useSkill(): void {
        let targets = this._actionData.targets;
        let caster = this._actionData.caster;
        let skill = new SkillBase(this._actionData.skill);
        skill.init(caster, targets);
        EventMgr.ins.event(EventId.CREATE_SKILL_ACTION, [caster, targets, skill])
        for (let i = 0; i < targets.length; i++) {
            skill.excute(caster, targets[i]);
        }
        //
        //根据结果给攻击方和受击方注册表现触发事件
        EventMgr.ins.event(EventId.DO_SHOW_SKILL, [caster])
    }

    /**角色死亡(如果在行动队列里，从队列里移除) */
    onRoleDead(role: BattleRole): void {
        let idx = this.actionQueue.indexOf(role);
        if (idx != -1) {
            this.actionQueue.splice(idx, 1)
        }
        let hasTeam = false;
        let hasEnemy = false;
        for (let i = 0; i < this.actionQueue.length; i++) {
            let role = this.actionQueue[i];
            if (role.roleData.group == "self") {
                hasTeam = true;
            } else if (role.roleData.group == "enemy") {
                hasEnemy = true;
            }
        }
        if (!hasEnemy) {
            EventMgr.ins.event(EventId.BATTLE_RESULT, true)
        } else if (!hasTeam) {
            EventMgr.ins.event(EventId.BATTLE_RESULT, false)
        }
    }

    /**执行当前行动 */
    doAction(): void {

    }

    /**获取当前行动单位 */
    public get curRole(): BattleRole {
        return this._curRole
    }

    /**buff生效-做一些处理-以及通知做表现 */
    onApplyBuff(applyData: any): void {

    }
}